package com.tinyengine.it.controller.engine.extend;


import com.tinyengine.it.common.base.Result;
import com.tinyengine.it.model.vo.RegisterRequest;
import com.tinyengine.it.security.AuthRequest;
import com.tinyengine.it.security.AuthResponse;
import com.tinyengine.it.security.JwtTokenUtil;
import com.tinyengine.it.security.RSAUtil;
import com.tinyengine.it.service.engine.extend.TUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Tag(name = "身份验证", description = "AuthController")
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
@Slf4j
public class AuthController {

    private final AuthenticationManager authenticationManager;
    private final UserDetailsService userDetailsService;
    private final JwtTokenUtil jwtTokenUtil;
    private final TUserService tUserService;
    private final RSAUtil rsaUtil;

    @Operation(summary = "获取RSA公钥", method = "GET")
    @GetMapping("/public-key")
    public Result<String> getPublicKey() {
        return Result.success(rsaUtil.getPublicKey());
    }

    @Operation(summary = "登录", method = "POST")
    @PostMapping("/login")
    public Result<?> login(@RequestBody AuthRequest authRequest) {
        try {
            // 解密密码
            String decryptedPassword = rsaUtil.decrypt(authRequest.getPassword());
            
            authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(authRequest.getUsername(), decryptedPassword)
            );

            final UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
            final String jwt = jwtTokenUtil.generateToken(userDetails);

            return Result.success(new AuthResponse(jwt));
        } catch (BadCredentialsException e) {
            return Result.failed("用户名或密码错误");
        } catch (Exception e) {
            log.error("登录失败: {}", e.getMessage());
            return Result.failed(e.getMessage());
        }
    }

    @Parameter(name = "Authorization", description = "令牌", in = ParameterIn.HEADER, required = true)
    @Operation(summary = "刷新令牌", method = "POST")
    @PostMapping("/refresh-token")
    public Result<?> refreshToken(@RequestHeader("Authorization") String token) {
        String username = jwtTokenUtil.getUsernameFromToken(token.substring(7));
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        String newToken = jwtTokenUtil.generateToken(userDetails);
        return Result.success(new AuthResponse(newToken));
    }

    @PostMapping("/register")
    @Operation(summary = "用户注册")
    public Result<?> register(@Valid @RequestBody RegisterRequest request) {
        // 检查用户名是否已存在
        if (tUserService.findByUsername(request.getUsername()) != null) {
            return Result.failed("用户名已存在");
        }

        // 创建新用户
        tUserService.createUser(
                request.getUsername(),
                request.getPassword(),
                request.getEmail()
        );

        return Result.success("注册成功");
    }

    @Parameter(name = "Authorization", description = "令牌", in = ParameterIn.HEADER, required = true)
    @Operation(summary = "用户登出", method = "POST")
    @PostMapping("/logout")
    public Result<?> logout(@RequestHeader("Authorization") String token) {
        try {
            // 从请求头中获取token
            String jwtToken = token.substring(7);
            // 将token加入黑名单（如果需要实现token失效功能）
            jwtTokenUtil.invalidateToken(jwtToken);
            return Result.success("登出成功");
        } catch (Exception e) {
            log.error("登出失败: {}", e.getMessage());
            return Result.failed("登出失败，请稍后重试");
        }
    }
}